// import page from "@/pages/template/page";
import {deepClone} from "@dcloudio/uni-h5/src/core/runtime/mp/polyfill/state/deep-clone";

const core = {
  /**
   * 是否为开发环境
   */
  isDev() {
    // #ifdef H5
    return process.env.NODE_ENV === 'development';
    // #endif
    // #ifdef MP-WEIXIN
    return uni.globalData.systemInfo.platform === 'devtools';
    // #endif
  },
  /**
   * 是否为生成环境
   */
  isProd() {
    // #ifdef H5
    return process.env.NODE_ENV !== 'development';
    // #endif
    // #ifdef MP-WEIXIN
    return uni.globalData.systemInfo.platform !== 'devtools';
    // #endif
  },

  /**
   * rpx 转 px
   */
  rpx2px(rpx) {
    return uni.globalData.systemInfo.screenWidth / 750 * rpx;
  },
  /**
   * px 转 rpx
   */
  px2rpx(rpx) {
    return rpx / (uni.globalData.systemInfo.screenWidth / 750);
  },
  /**
   * 返回上一页，如果上一页不存在则返回首页
   */
  navigateBack() {
    if (getCurrentPages().length > 1) {
      uni.navigateBack();
    } else {
      core.toIndex()
    }
  },
  /**
   * 跳转到某个页面，首先尝试使用 uni.navigateTo 跳转，如果失败则用 uni.switchTab 跳转
   */
  navigateTo(url) {
    uni.navigateTo({
      url,
      fail() {
        uni.switchTab({
          url
        })
      }
    })
  },
  /**
   * 跳转到首页
   */
  toIndex() {
    // uni.switchTab({
    //     url: "/pages/index/index"
    // })
    const indexRoute = '/';
    let pages = getCurrentPages();
    let length = pages.length;
    if (length == 1) {
      uni.redirectTo({url: indexRoute})
    } else if (length > 1) {
      uni.navigateBack({delta: length})
      setTimeout(_ => uni.redirectTo({url: indexRoute}), 100)
    }

  },
  /**
   * 跳转到登录页面
   * @param {String|Number} loginType 1 账号密码登录，2短信验证码登录
   */
  toLogin(loginType) {
    // let url = "/pages/login/login?loginType=" + loginType || '2'
    let url = "/pages/login/index"
    // #ifdef MP-WEIXIN
    url = "/pages/login/index"
    // #endif

    uni.navigateTo({
      url
    })
  },
  /**
   * 退出登录，清除所有页面，并跳转到登录页
   */
  loginOut() {
    uni.req.setToken("");
    uni.req.setUserInfoCache(null);

    let url = "/pages/user/login/login"

    // #ifdef MP-WEIXIN
    url = "/pages/user/login/wx-mp-login"
    // #endif

    uni.reLaunch({
      url
    })
  },

  /**
   * 跳转到指定文章页面
   * @param {Inter || String} id
   */
  toArticle(id) {
    uni.navigateTo({
      url: "/pages/top/article?id=" + id
    })
  },

  /**
   * 跳转到指定 web-view 页面
   * @param {String} src
   */
  toWebView(src) {
    uni.navigateTo({
      url: core.addQueryString("/pages/top/web-view", {
        src
      })
    })
  },
  /**
   * 随机获得数组中的某个元素
   * @param {Array} list
   */
  getRandomItem(list) {
    return list[parseInt(Math.random() * list.length)]
  },

  /**
   * 隐藏手机号中间 4 位数
   */
  hidePhone(phone) {
    if (Number(phone) && phone.length === 11) {
      return phone.replace(/^(\d{3})\d{4}(\d{4})$/, '$1****$2')
    } else {
      return phone
    }
  },
  /**
   * 校验是否为手机号
   * @param {Object} phone 手机号
   * @return {Boolean} true 是手机号，false 不是手机号
   */
  checkPhone(phone) {
    return /^1[3456789]\d{9}$/.test(phone);
  },
  /**
   * 将键值对转换成查询参数，例如{'name':'admin','age':18}转换成 'name=admin&age=18'
   * @param {Object} data 要转换的键值对
   */
  parseQueryString(data) {
    if (typeof data === "string") {
      return data;
    }
    let list = []
    for (let key in data) {
      let value = data[key];
      if (value !== undefined && value !== null)
        list.push(encodeURI(key) + "=" + encodeURI(value))
    }
    return list.join("&");
  },
  /**
   * 将url拼接上查询参数，自动将键值对转换成查询参数，例如{'name':'admin','age':18}转换成 'name=admin&age=18'
   * @param {String} url 原始链接
   * @param {Object} data 要转换的键值对
   */
  addQueryString(url, data) {
    url = url || "";
    const queryString = core.parseQueryString(data);
    if (!queryString) {
      return url;
    }

    if (url.indexOf("?") === -1) {
      url += "?";
    }
    if (!url.endsWith("?") && !url.endsWith("&")) {
      url += "&";
    }
    return url += queryString;
  },
  /**
   * 把指定url里面的参数转换为map
   * @param {String} url 完整的 url 或 queryString
   */
  parseParameterMap: function (url) {
    if (!url) return {};
    let query = core.splitUrl(url)[1];
    if (!query) return {};
    let parameterList = query.split("&"); //获取所有参数
    let parameterMap = {};
    for (let parameter of parameterList) { //遍历所有参数
      parameter = parameter.split("=");
      if (!parameter[0]) continue
      parameterMap[decodeURI(parameter[0])] = decodeURI(parameter[1] || "");
    }
    return parameterMap;
  },
  /**
   * 分隔 url，把 /pages/my?a=1&b=2#h2 分隔成 ['/pages/my','a=1&b=2','h2']
   */
  splitUrl(url) {
    if (!url) return ["", "", ""];
    var list = url.replace("#", "?").split("?");
    if (url.indexOf("?") > -1 && url.indexOf("#") > -1) return list;
    if (url.indexOf("?") === -1 && url.indexOf("#") === -1) return [list[0], "", ""];
    if (url.indexOf("?") === -1) return [list[0], "", list[1]];
    if (url.indexOf("#") === -1) return [list[0], list[1], ""];
  },
  /**
   * 将目标路径与当前页面路径合并，获得目标路径的绝对路径
   * 例如："pages/abc/def?a=1#c",".././home?id=1#d" 将合并成 "pages/home?id=1#d"
   */
  mergeUrl(url1, url2) {
    if (url2.startsWith("/")) return url2;

    var url2Split = core.splitUrl(url2);
    var dir1List = core.splitUrl(url1)[0].split("/");
    dir1List.pop();
    var dirList = dir1List.concat(url2Split[0].split("/"));
    var newDirList = [];

    for (var i = 0; i < dirList.length; i++) {
      let item = dirList[i];
      if (item === ".") continue;
      if (item === "..") {
        newDirList.pop();
        continue;
      }
      newDirList.push(item);
    }

    var newUrl = newDirList.join("/");
    if (url2Split[1]) newUrl += "?" + url2Split[1];
    if (url2Split[2]) newUrl += "#" + url2Split[2];
    return newUrl;
  },
  /**
   * 保存邀请码
   */
  setInviteCode(code) {
    uni.setStorageSync("inviteCode", code)
  },
  /**
   * 获取邀请码
   */
  getInviteCode(code) {
    return uni.getStorageSync("inviteCode")
  },
  /**
   * 刷新H5的 token，实际上H5无需刷新，这里只是进行标记刷新已完成
   */
  refreshTokenForH5() {
    uni.globalData.tokenRefreshed = true;
  },
  /**
   * 刷新微信小程序的 token，实际上就是获取微信信息然后向后台登录
   * @param {Object} force 失败时强制跳转到登录页面
   */
  refreshTokenForMpWeixin(force) {
    uni.globalData.tokenRefreshed = false;

    uni.login({
      provider: 'weixin',
      success: loginRes => {
        console.log("请求登录信息", loginRes);
        uni.getUserInfo({
          provider: 'weixin',
          success: info => {
            console.log('用户信息', info);

            //许的版本
            info.code = loginRes.code;
            info.inviteCode = core.getInviteCode();
            uni.req.postJ("/client/user/mp-wechat-login", info, res => {
              console.log("刷新token成功！")
            }, _ => {
              uni.globalData.tokenRefreshed = true;
            }, _ => {
              console.log("刷新token失败！")
            })

            //李的版本
            // info.code = loginRes.code;
            // info.mid = core.getInviteCode();
            // uni.req.postJ("/api/index/login", info, res => {
            //     console.log("刷新token成功！")
            // }, _ => {
            //     uni.globalData.tokenRefreshed = true;
            // }, _ => {
            //     console.log("刷新token失败！")
            // })

            //杨的版本
            // uni.req.get("/api/user/wxLogin", {
            //     code: loginRes.code
            // }, res => setTimeout(_ => {
            //     uni.req.get("/api/user/getToken", {
            //         open_id: res.openid,
            //         session_key: res.session_key,
            //         username: info.userInfo.nickName,
            //         head_img: info.userInfo.avatarUrl,
            //         pid: core.getInviteCode()
            //     }, res => {
            //         if (res.token) uni.req.setToken(res.token)
            //         console.log("刷新token成功！")
            //     }, _ => {
            //         uni.globalData.tokenRefreshed = true;
            //     }, _ => {
            //         console.log("刷新token失败！")
            //     })
            // }), null, _ => {
            //     uni.globalData.tokenRefreshed = true;
            //     console.log("刷新token失败！")
            // })
          },
          fail: () => {
            console.log("获取用户信息失败，强制登录：" + (force ? true : false))
            if (force) core.toLogin()
            uni.globalData.tokenRefreshed = true;
          }
        });
      },
      fail() {
        uni.globalData.tokenRefreshed = true
      }
    });


  },

  /**
   * 在刷新微信小程序从后台切到前台后会刷新 token，这个方法将在刷新完成后回调，如果不需要刷新或已刷新则立即回调
   * @param {Function} func 回调函数
   */
  onTokenRefreshed4Show(func) {
    if (uni.globalData.tokenRefreshed) {
      if (typeof func === "function") setTimeout(func)
    } else {
      setTimeout(core.onTokenRefreshed4Show, 100, func)
    }
  },

  /**
   * 格式化日期，更多日期时间处理请使用 http://momentjs.cn/
   * @param {String} format 日期格式字符串
   * @param {Date} date 要格式化的日期时间对象，可以是字符串，时间戳，Date对象，不传取当前时间
   */
  formatDate(format, date) {
    date = core.parseDate(date);
    const o = {
      "M+": date.getMonth() + 1, //月份
      "d+": date.getDate(), //日
      "h+": date.getHours(), //小时
      "m+": date.getMinutes(), //分
      "s+": date.getSeconds(), //秒
      "q+": Math.floor((date.getMonth() + 3) / 3), //季度
      "S": date.getMilliseconds().toString().padEnd(3, '0') //毫秒
    };
    if (/(y+)/.test(format))
      format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (let k in o)
      if (new RegExp("(" + k + ")").test(format))
        format = format.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[
            k]).length)));
    return format;
  },
  /**
   * 格式化日期为 yyyy-MM-dd hh:mm:ss 格式
   * @param {Date} date
   */
  formatDate_yyyyMMddhhmmss(date) {
    return core.formatDate("yyyy-MM-dd hh:mm:ss", date)
  },
  /**
   * 格式化日期为 yyyy-MM-dd hh:mm 格式
   * @param {Date} date
   */
  formatDate_yyyyMMddhhmm(date) {
    return core.formatDate("yyyy-MM-dd hh:mm", date)
  },
  /**
   * 格式化日期为 yyyy-MM-dd 格式
   * @param {Date} date
   */
  formatDate_yyyyMMdd(date) {
    return core.formatDate("yyyy-MM-dd", date)
  },
  /**
   * 智能的将日期格式化成：刚刚，3分钟前，1小时前，2天前，1周前，2月前，3年前
   * @param {Date} time
   */
  formaDate_auto(time) {
    var dateTimeStamp = core.parseDate(time).getTime()

    var minute = 1000 * 60;
    var hour = minute * 60;
    var day = hour * 24;

    var month = day * 30;
    var year = month * 12;
    var now = new Date().getTime();
    var diffValue = now - dateTimeStamp;
    var result = ""
    if (diffValue < 0) {
      return;
    }

    var monthC = diffValue / month;
    var weekC = diffValue / (7 * day);
    var dayC = diffValue / day;
    var hourC = diffValue / hour;
    var minC = diffValue / minute;
    var yearC = diffValue / year
    if (yearC >= 1) {
      return "" + parseInt(yearC) + "年前";
    }
    if (monthC >= 1) {
      result = "" + parseInt(monthC) + "月前";
    } else if (weekC >= 1) {
      result = "" + parseInt(weekC) + "周前";
    } else if (dayC >= 1) {
      result = "" + parseInt(dayC) + "天前";
    } else if (hourC >= 1) {
      result = "" + parseInt(hourC) + "小时前";
    } else if (minC >= 1) {
      result = "" + parseInt(minC) + "分钟前";
    } else {
      result = "刚刚";
    }
    return result;
  },
  /**
   * 将字符串、时间戳等转换成日期时间对象
   * @param {Number,String,Date} date 要转换的时间
   * @param {Number,String,Date} defaultDate 转换失败返回的默认值
   */
  parseDate(date, defaultDate) {
    if (typeof date === "number" && date.toString().length === 10) { //兼容精确到秒的 10 位时间戳
      date *= 1000;
    }
    if (typeof date === "string") { //兼容 ios 格式问题
      date = date.replace(/\-/g, "/");
    }
    return date ? new Date(date) : defaultDate;
  },
  /**
   * 比较两个日期大小,ate1 == date2 返回0，date1 > date2 返回1，date1 < date2 返回-1
   */
  dateCompareTo(date1, date2) {
    date1 = core.parseDate(date1).getTime();
    date2 = core.parseDate(date2).getTime();
    if (date1 == date2) return 0;
    return date1 > date2 ? 1 : -1;
  },
  /**
   * 计算两个时间的间隔。返回一个数组 ["0", "00", "01", "05"] 分别代表 天，小时，分钟，秒
   * @param {Date} start 开始时间
   * @param {Date} start 结束时间，不传为当前时间
   */
  countDownByDate(start, end) {
    if (!start) return ["0", "00", "00", "00"];
    start = core.parseDate(start).getTime();
    var end = end ? core.parseDate(end).getTime() : Date.now().getTime();
    var interval = start > end ? start - end : end - start;
    return core.countDownByInterval(interval / 1000);
  },
  /**
   * 日期时间间隔转换。返回一个数组 [0, "00", "01", "05"] 分别代表 天，小时，分钟，秒
   * @param {Number} interval 间隔（秒）不能为负数，例如 65 将返回 ["0", "00", "01", "05"]
   */
  countDownByInterval(interval) {
    interval = parseInt(interval);
    if (!interval) return ["0", "00", "00", "00"];

    var day = Math.floor(interval / 86400);
    var hour = Math.floor((interval - 24 * day * 60 * 60) / 3600);
    var minute = Math.floor((interval - 24 * day * 60 * 60 - 3600 * hour) / 60);
    var second = Math.floor(interval - 24 * day * 60 * 60 - 3600 * hour - 60 * minute);
    return [
      day.toString(),
      hour < 10 ? "0" + hour : hour.toString(),
      minute < 10 ? "0" + minute : minute.toString(),
      second < 10 ? "0" + second : second.toString()
    ]
  },
  /**
   * 格式化并返回文件大小字符串，单位支持 B、KB、MB、GB，例如：14.94KB、0.26MB 等
   * @param {Number} size
   */
  formatSize(size) {
    if (size < 100) {
      return size + "B";
    } else if (size < 100 * 1024) {
      return (size / 1024).toFixed(2) + "KB";
    } else if (size < 100 * 1024 * 1024) {
      return (size / 1024 / 1024).toFixed(2) + "MB";
    } else if (size < 100 * 1024 * 1024 * 1024) {
      return (size / 1024 / 1024 / 1024).toFixed(2) + "GB";
    }
  },
  /**
   * 获取位置，会自动建立位置缓存，缓存60秒，回调参数中 cache 表示是否为缓存，timestamp表示数据获取时间
   * @param {Function} success 成功回调函数
   * @param {Function} [complete] 无轮成功或失败都会回调
   * @param {Function} [fail] 失败回调函数，返回 false 不会弹出默认失败弹窗，如果返回一个函数，那么将会在用户点击弹窗按钮时调用
   * @param {Boolean} [force] 是否忽略缓存，强制重新获取
   */
  getLocation(success, complete, fail, force) {

    //检测缓存是否有效
    if (force || (uni.globalData.location && uni.globalData.location.timestamp + 60 * 1000 > new Date().getTime())) {
      if (typeof success === "function") {
        uni.globalData.location.cache = true;
        setTimeout(success, 0, uni.globalData.location);
        return;
      }
    }

    core.showLoading("定位中");
    uni.getLocation({
      success: res => {
        res.timestamp = new Date().getTime();
        res.cache = false;
        uni.globalData.location = res;
        console.log("定位", res);
        if (typeof success === "function") {
          success(uni.globalData.location);
        }
      },
      fail: e => {
        console.log("自动定位失败：", e);
        let modalSuccess = null;
        if (typeof fail === "function") {
          modalSuccess = fail(e)
          if (modalSuccess === false) return;
        }
        if (e.errMsg.indexOf("fail auth deny") > -1) {
          uni.showModal({
            title: "获取位置失败",
            content: "请在小程序设置中允许获取位置信息后重试",
            showCancel: false,
            success: typeof modalSuccess === "function" ? modalSuccess : _ => {
            }
          })
        } else if (e.errCode === 2) {
          uni.showModal({
            title: "获取位置失败",
            content: "请打开 GPS 位置后重试",
            showCancel: false,
            success: typeof modalSuccess === "function" ? modalSuccess : _ => {
            }
          })
        }
      },
      complete: e => {
        uni.hideLoading()
        if (typeof ccomplete === "function") ccomplete(e)
      }
    })
  },
  /**
   * 存储位置数据，通常用于保存 uni.chooseLocation 方法获得的位置数据，防止 core.getLocation 获取不到缓存位置导致一直弹出错误提示,
   * 要想数据一直有效，请将 location.timestamp 设置为 9999999999999
   * @param {Location} location 位置对象
   */
  storageLocation(location) {
    if (!location.timestamp) location.timestamp = new Date().getTime()
    uni.globalData.location = location;
  },
  /**
   * 清除存储的位置数据
   */
  clearLocation() {
    delete uni.globalData.location;
  },
  /**
   * 根据经纬度来计算直线距离，单位为千米
   * @param {Object} lng1 经度1
   * @param {Object} lat1 维度1
   * @param {Object} lng2 经度2
   * @param {Object} lat2 维度2
   */
  getDistance(lng1, lat1, lng2, lat2) {
    var radLat1 = lat1 * Math.PI / 180.0
    var radLat2 = lat2 * Math.PI / 180.0
    var a = radLat1 - radLat2
    var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0
    var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
        Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)))
    s = s * 6378.137 // EARTH_RADIUS;
    s = Math.round(s * 10000) / 10000
    return s
  },
  /**
   * 根据经纬度来计算直线距离，并格式化为中文单位，例如 512米、1.6千米
   * @param {Object} lng1 经度1
   * @param {Object} lat1 维度1
   * @param {Object} lng2 经度2
   * @param {Object} lat2 维度2
   */
  getDistanceCN(lng1, lat1, lng2, lat2) {
    return core.formateDistanceCN(core.getDistance(lng1, lat1, lng2, lat2))
  },
  /**
   * 根据经纬度来计算直线距离，并格式化为英文单位，例如 512米、1.6千米
   * @param {Object} lng1 经度1
   * @param {Object} lat1 维度1
   * @param {Object} lng2 经度2
   * @param {Object} lat2 维度2
   */
  getDistanceEN(lng1, lat1, lng2, lat2) {
    return core.formateDistanceEN(core.getDistance(lng1, lat1, lng2, lat2))
  },
  /**
   * 格式化距离，输出中文单位，例如 512m、1.6km
   * @param {Number} distance 距离，单位千米
   */
  formateDistanceCN(distance) {
    distance = parseFloat(distance)
    return distance < 1 ? parseInt(distance * 1000) + "米" : distance.toFixed(1) + "千米"
  },
  /**
   * 格式化距离，输出英文单位，例如 512m、1.6km
   * @param {Number} distance 距离，单位千米
   */
  formateDistanceEN(distance) {
    distance = parseFloat(distance)
    return distance < 1 ? parseInt(distance * 1000) + "m" : distance.toFixed(1) + "km"
  },
  /**
   * 弹出一个无图标的 toast
   * @param {String} title
   */
  showToast(title) {
    uni.showToast({
      icon: "none",
      title
    })
  },
  /**
   * 弹出一个默认图标的 toast
   */
  showToastIcon(title) {
    uni.showToast({
      title
    })
  },
  /**
   * 显示一个指定 title 的 loading弹框，默认 title 为“加载中”
   */
  showLoading(title) {
    uni.showLoading({
      title: title || "加载中"
    })
  },
  /**
   * 复制文本到系统剪贴板的内容
   */
  setClipboardData(text) {
    if (typeof text !== "string") text = text + '';
    console.log("复制内容", text);

    // #ifdef H5
    if (!document.queryCommandSupported('copy')) core.showToast("复制失败，请更换浏览器后重试");
    let textarea = document.createElement("textarea");
    textarea.value = text;
    textarea.readOnly = "readOnly";
    document.body.appendChild(textarea);
    textarea.select(); // 选择对象
    textarea.setSelectionRange(0, text.length); //核心
    let result = document.execCommand("copy"); // 执行浏览器复制命令
    textarea.remove();
    core.showToast(result ? "复制成功" : "复制失败");
    // #endif

    // #ifndef H5
    uni.setClipboardData({
      data: text,
      success: _ => core.showToast("复制成功"),
      fail: _ => core.showToast("复制失败")
    })
    // #endif
  },
  /**
   * 判断当前是否为微信环境，是返回 true，不是返回 false
   * @return {Boolean} 是返回 true，不是返回 false
   */
  isWxClient() {
    return navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == "micromessenger";
  },
  /**
   * 检测当前是否为微信环境，不是微信环境则弹出提示，是返回 true，不是返回 false
   * @return {Boolean} 是返回 true，不是返回 false
   */
  checkWxClient() {
    var is = core.isWxClient();
    if (!is) {
      uni.showModal({
        title: "提示",
        content: "请在微信客户端中打开！",
        showCancel: false,
      })
    }
    return is;
  },
  /**
   * 微信公众号支付
   * @param {Object} data 支付参数，例如：
   *  <p>appId: "wxa601d89d82abc693"</p>
   *  <p>nonceStr: "kpoelxMp3p6wsGNG"</p>
   *  <p>package: "prepay_id=wx16175501465812b9cc06b4b61372451100"</p>
   *  <p>paySign: "D12A4BDE4F35D4B4A7E1364380D4FD76"</p>
   *  <p>signType: "MD5"</p>
   *  <p>timeStamp: "1592301304"</p>
   *
   * @param {Function} success 支付成功回调函数，不传使用默认的
   * @param {Function} cancel 支付取消回调函数，不传使用默认的
   * @param {Function} fail 支付失败回调函数，不传使用默认的
   *
   */
  wxClientPay(data, success, cancel, fail) {
    if (!core.checkWxClient()) return;
    WeixinJSBridge.invoke('getBrandWCPayRequest', data, res => {
      WeixinJSBridge.log(res.err_msg);
      if (res.err_msg == 'get_brand_wcpay_request:ok') {
        if (typeof success === "function") {
          success(res)
        } else core.showToastIcon("支付成功");
      } else if (res.err_msg == 'get_brand_wcpay_request:cancel') {
        if (typeof cancel === "function") {
          cancel(res);
        } else {
          uni.showModal({
            title: '支付取消',
            content: '您取消了支付！',
            showCancel: false
          });
        }

      } else if (res.err_msg == 'get_brand_wcpay_request:fail') {
        if (typeof fail === "function") {
          fail(res)
        } else {
          uni.showModal({
            title: '支付失败',
            content: '支付失败，请联系客服！',
            showCancel: false
          });
        }

      }
    });
  },
  /**
   * 微信小程序支付
   * @param {Object} data 支付参数
   * @param {Function} [success] 支付成功回调函数，不传使用默认的
   * @param {Function} [cancel] 支付取消回调函数，不传使用默认的
   * @param {Function} [fail] 支付失败回调函数，不传使用默认的
   *
   */
  wxMpPay(data, success, cancel, fail) {
    data.appId = data.appid;
    data.nonceStr = data.noncestr;
    data.paySign = data.paysign;
    data.signType = data.signtype;
    data.timeStamp = data.timestamp;


    data.success = res => {
      if (typeof success === "function") {
        success(res)
      } else core.showToastIcon("支付成功");
    }
    data.fail = res => {
      console.log(res)
      if (res.errMsg == "requestPayment:fail cancel") {
        if (typeof cancel === "function") {
          cancel(res);
        } else {
          // uni.showModal({
          //   title: '支付取消',
          //   content: '您取消了支付！',
          //   showCancel: false
          // });
          uni.showToast({title: '支付已取消', icon: 'none'})
        }
      } else {
        if (typeof fail === "function") {
          fail(res)
        } else {
          // uni.showModal({
          //   title: '支付失败',
          //   content: '支付失败，请联系客服！',
          //   showCancel: false
          // });
          uni.showToast({title: '支付失败，请联系客服！', icon: 'none'})
        }
      }
    }
    console.log(data)
    uni.requestPayment(data);
  },
  /**
   * 获得 16 位的 uuid，基数 62，这个不是标准的 uuid
   */
  uuidShort() {
    return core.uuid(16, 62)
  },
  /**
   * 获得 uuid
   * @param len 长度，默认32
   * @param radix 基数，支持 2-62，默认16
   */
  uuid(len, radix) {
    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
    var uuid = [],
        i;
    radix = radix || chars.length;

    if (len) {
      // Compact form
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
    } else {
      // rfc4122, version 4 form
      var r;

      // rfc4122 requires these characters
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
      uuid[14] = '4';

      // Fill in random data.  At i==19 set the high bits of clock sequence as
      // per rfc4122, sec. 4.1.5
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16;
          uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r];
        }
      }
    }

    return uuid.join('');
  },
  getPrevPage() {
    let pages = getCurrentPages();  //获取所有页面栈实例列表
    if (!pages || pages.length == 1) return null;

    return pages[pages.length - 2]
  },
  deepClone(model) {
    return deepClone(model);
  },
  /**
   * 执行上一页的函数
   * @param methodName {string} 函数名
   * @param [params] {*} 参数
   */
  prePageHandleMethod(methodName, ...params) {
    let prePage = this.getPrevPage();
    console.log(prePage)
    if (prePage) {
      if (typeof prePage[methodName] === 'function') {
        prePage[methodName](...params);
      } else if (prePage.$vm && typeof prePage.$vm[methodName] === 'function') {
        prePage.$vm[methodName](...params);
      }
    }
  },
  /**
   * 解码
   * @param obj {*} 对象
   * @param params {string} 要解码的参数名，不传则全部解码
   */
  decodeURIComponentObject(obj, ...params) {
    if (obj) {
      let all = params.length == 0;
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          let value = obj[key];
          if (all || params.indexOf(key) > 0) {
            obj[key] = decodeURIComponent(value);
          }
        }
      }
    }
    return obj
  },

};


// #ifdef H5
// 生产环境隐藏日志，可通过 uni.core.showLog() 方法重新开启
(_ => {
  const trace = console.trace;
  const debug = console.debug;
  const info = console.info;
  const log = console.log;
  const error = console.error;
  const warn = console.warn;

  if (core.isProd()) {
    console.trace = _ => {
    };
    console.debug = _ => {
    };
    console.info = _ => {
    };
    console.log = _ => {
    };
    console.error = _ => {
    };
    console.warn = _ => {
    };
  }

  core.showLog = function () {
    console.trace = trace;
    console.debug = debug;
    console.info = info;
    console.log = log;
    console.error = error;
    console.warn = warn;
  }
})();
// #endif

export default core;
